﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Configuration;
using System.Xml;
using System.Collections;


namespace SearchUI.Models
{

	public class SearchResult : IComparable
	{
		public string Index { get; set; }
		public string Path { get; set; }
		public string Name { get; set; }
		public DateTime ModTime { get; set; }
		public Int64 SizeInBytes { get; set; }
		public string HREF { get; set; }
		public string DisplayPath { get; set; }
		public string Ext { get; set; }
		public Int32 Rank { get; set; }
		public bool ReverseSort { get; set; }

		public CompareField SortBy { get; set; }

		#region IComparable Members

		public int CompareTo(object y)
		{
			int result = 0;
			switch (this.SortBy)
			{
				
				case CompareField.Rank:
					result = ((SearchResult)y).Rank.CompareTo(Rank);
					break;
				case CompareField.Path:
					result = String.Compare(((SearchResult)this).Path.ToString(), ((SearchResult)y).Path.ToString());
					break;
				case CompareField.Name:
					result = String.Compare(((SearchResult)this).Name.ToString(), ((SearchResult)y).Name.ToString());
					break;
				case CompareField.ModifiedDate:
					result = DateTime.Compare(((SearchResult)y).ModTime, ((SearchResult)this).ModTime);
					break;
				case CompareField.Size:
					result = ((SearchResult)y).SizeInBytes.CompareTo(SizeInBytes);
					break;
				default:
					result = 0;
					break;
			}
			
			if (this.ReverseSort)
			{
				if (result == 1)
				{
					return 2;
				}
				else if (result == 2)
				{
					return 1;
				}
				else
				{
					return 0;
				}
			}
			else
			{
				return result;
			}


		#endregion
		}
	}



	public enum CompareField
	{
		Rank,
		Path,
		Name,
		ModifiedDate,
		Size
	}

	public class SearchModel
	{

		public SearchResult[] ResultsArray { get; set; }
		public int NumberOfResults { get; set; }
		public bool SearchHasErrors { get; set; }
		public string SearchErrors { get; set; }
		public string SearchTerms { get; set; }
		public string SortedBy { get; set; }
		public string ReverseSort{ get; set; }
		public string SearchTitle { get; set; }

		public void RunSWISHESearch(string search_terms, string search_id, CompareField sortBy, string reverseSort, string format)
		{
			using (Process p2 = new Process())
			{
				string XMLSearchIndexPath = ConfigurationManager.AppSettings["XMLSearchIndex"].ToString();
				XmlDocument xDocument = new XmlDocument();
				xDocument.Load(XMLSearchIndexPath);
				string searchKey = String.Empty;

				XmlElement xSearch = xDocument.GetElementById(search_id);

				if (xSearch == null)
				{
					this.SearchHasErrors = true;
					this.SearchErrors = "The requested repository does not exist";
					return;
				}
				this.SearchTerms = search_terms;
				this.SortedBy = sortBy.ToString();
				this.ReverseSort = reverseSort;
				string subFrom = xSearch.Attributes["FileSystemPathRoot"].Value.ToString();
				string subTo = xSearch.Attributes["URLPathRoot"].Value.ToString();
				SearchTitle = xSearch.Attributes["SearchName"].Value.ToString();
				
				p2.StartInfo.UseShellExecute = false;
				p2.StartInfo.CreateNoWindow = true;
				p2.StartInfo.FileName = xSearch.Attributes["SwishESearchBatchFile"].Value.ToString();
				p2.StartInfo.WorkingDirectory = xSearch.Attributes["SwishESearchWorkingDir"].Value.ToString();
				Guid myGuide = System.Guid.NewGuid();
				string ApplicationFilePath = System.Web.Hosting.HostingEnvironment.MapPath(@"~/App_Data");
				string diffPath = System.IO.Path.Combine(ApplicationFilePath, myGuide.ToString() + ".results");
				p2.StartInfo.Arguments = '"' + search_terms + '"' + " " + diffPath;
				p2.Start();
				p2.WaitForExit();

				StringBuilder sb = new StringBuilder(string.Empty);
				using (FileStream inputStream = new FileStream(diffPath, FileMode.Open, FileAccess.Read))
				{
					using (StreamReader streamReader = new StreamReader(inputStream))
					{

						while (!streamReader.EndOfStream)
						{
							sb.Append(streamReader.ReadLine() + Environment.NewLine);
						};
						streamReader.Close();
						inputStream.Close();

					}
				}
				string[] resultsStringList = sb.ToString().Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
				List<String[]> matchingLines = new List<String[]>();
				foreach (string resultString in resultsStringList)
				{

					if (format != null && format != String.Empty)
					{
						string[] parts = resultString.Split('|');
						if (System.IO.Path.GetExtension(parts[3].ToString()).ToUpper().Contains(format.ToUpper()))
						{
							matchingLines.Add(parts);
						}
					}
					else
					{
						string[] parts = resultString.Split('|');
						matchingLines.Add(parts);
					}
				}
				int count = resultsStringList.Count();
				SearchResult[] results = new SearchResult[matchingLines.Count];

				int index = 0;
				foreach (string[] parts in matchingLines)
				{
					results[index] = new SearchResult();
					results[index].SortBy = sortBy;
					if (ReverseSort == "1" )
					{
						results[index].ReverseSort = true;
					}
					else
					{
						results[index].ReverseSort = false;
					}
					results[index].Index = parts[0].ToString();
					results[index].Rank = Int32.Parse(parts[1].ToString());
					results[index].ModTime = DateTime.Parse(parts[2].ToString());
					results[index].Path = parts[3].ToString();
					results[index].SizeInBytes = Int64.Parse(parts[4].ToString());
					results[index].Name = parts[5].ToString();
					results[index].Ext = System.IO.Path.GetExtension(results[index].Path);
					results[index].HREF = results[index].Path.Replace(subFrom, subTo);
					results[index].DisplayPath = results[index].Path.Replace(subFrom, String.Empty);
					index++;
				}
				ResultsArray = results;

				System.IO.File.Delete(diffPath);
			}
		}

	}
}
